package org.example.controller;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.example.bean.enums.*;
import org.example.bean.req.DrillViewConfigReq;
import org.example.bean.req.DynamicViewConfigReq;
import org.example.bean.res.DynamicViewConfigRes;
import org.example.bean.vo.*;
import org.example.dao.entity.DynamicViewColumn;
import org.example.dao.entity.DynamicViewConfig;
import org.example.dao.entity.DynamicViewGroup;
import org.example.dao.mapper.DynamicViewColumnMapper;
import org.example.dao.mapper.DynamicViewConfigMapper;
import org.example.dao.mapper.DynamicViewGroupMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.*;
import java.util.stream.Collectors;

import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 动态展示配置表 前端控制器
 *
 * @author yang jun
 * @since 2024-05-21
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping(value = "/dynamic-view-config")
@Api(value = "/dynamic-view-config", tags = {"动态展示配置表接口"})
public class DynamicViewConfigController {

    private final DynamicViewGroupMapper dynamicViewGroupMapper;
    private final DynamicViewConfigMapper dynamicViewConfigMapper;
    private final DynamicViewColumnMapper dynamicViewColumnMapper;

    @GetMapping("/drill")
    @ApiOperation("获取下钻得页面配置信息")
    public Object queryDrillDynamicViewConfig(DrillViewConfigReq req) {
        List<DrillViewConfigVo> list = new ArrayList<>();
        DynamicViewConfig viewConfig = dynamicViewConfigMapper.selectById(req.getId());
        JSONObject extra = viewConfig.getExtra();
        Collection<?> groupKeys = (Collection<?>) JSONPath.eval(extra, "$.drillConfigs");
        if (CollectionUtils.isNotEmpty(groupKeys)) {
            LambdaQueryWrapper<DynamicViewConfig> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(DynamicViewConfig::getGroupId, viewConfig.getGroupId());
            wrapper.orderByAsc(DynamicViewConfig::getSortOrder);
            List<DynamicViewConfig> viewConfigs = dynamicViewConfigMapper.selectList(wrapper);
            for (Object o : groupKeys) {
                JSONObject obj = JSONObject.parseObject(JSONObject.toJSONString(o));
                String type = obj.getString("type");
                DynamicViewConfig config = getDynamicViewConfigByCategory(viewConfigs, type);
                List<DynamicViewColumn> columnList = getDynamicViewColumnsByViewId(config.getId(), req.getFunctionType());

                DrillViewConfigVo configVo = new DrillViewConfigVo();
                configVo.setExtra(config.getExtra());
                configVo.setSubTypeName(config.getSubTypeName());
                configVo.setColumnList(columnList);
                list.add(configVo);
            }
        } else {
            DynamicViewConfig config = dynamicViewConfigMapper.selectById(req.getId());
            DrillViewConfigVo configVo = new DrillViewConfigVo();
            configVo.setExtra(config.getExtra());
            configVo.setSubTypeName(config.getSubTypeName());
            List<DynamicViewColumn> columnList = getDynamicViewColumnsByViewId(config.getId(), req.getFunctionType());
            configVo.setColumnList(columnList);
            list.add(configVo);
        }
        return list;
    }

    private DynamicViewConfig getDynamicViewConfigByCategory(List<DynamicViewConfig> viewConfigs, String category) {
        for (DynamicViewConfig viewConfig : viewConfigs) {
            if (Objects.equals(category, viewConfig.getCategory())) {
                return viewConfig;
            }
        }
        return null;
    }

    private List<DynamicViewColumn> getDynamicViewColumnsByViewId(Integer viewId, Integer functionType) {
        LambdaQueryWrapper<DynamicViewColumn> queryWrapper2 = Wrappers.lambdaQuery();
        queryWrapper2.eq(DynamicViewColumn::getViewId, viewId);
        queryWrapper2.eq(DynamicViewColumn::getFunctionType, functionType);
        queryWrapper2.orderByAsc(DynamicViewColumn::getSortOrder);
        return dynamicViewColumnMapper.selectList(queryWrapper2);
    }

    /**
     * http://localhost:8081/dynamic-view-config?dateType=0&functionType=0
     */
    @GetMapping("")
    @ApiOperation("获取页面配置信息")
    public DynamicViewConfigRes queryDynamicViewConfig(DynamicViewConfigReq req) {
        DynamicViewConfigRes res = new DynamicViewConfigRes();
        res.setWidgetVoList(getDynamicViewConfigs(req));
        return res;
    }

    private List<WidgetVo> getDynamicViewConfigs(DynamicViewConfigReq req) {
        // 今日 首页
        LambdaQueryWrapper<DynamicViewGroup> groupWrapper = Wrappers.lambdaQuery();
        groupWrapper.eq(DynamicViewGroup::getDateType, req.getDateType());
        groupWrapper.eq(DynamicViewGroup::getFunctionType, req.getFunctionType());
        groupWrapper.orderByAsc(DynamicViewGroup::getSortOrder);
        List<DynamicViewGroup> viewGroups = dynamicViewGroupMapper.selectList(groupWrapper);

        // 拍机堂, 机大侠
        Map<Integer, List<DynamicViewGroup>> map = viewGroups.stream().collect(Collectors.groupingBy(DynamicViewGroup::getDataSource));
        List<Integer> dataSources = viewGroups.stream().map(DynamicViewGroup::getDataSource).distinct().collect(Collectors.toList());

        List<WidgetVo> widgetVoList = new ArrayList<>();
        for (Integer dataSource : dataSources) {
            List<DynamicViewGroup> groups = map.get(dataSource);
            WidgetVo groupVo = new WidgetVo();
            groupVo.setDataSource(dataSource);
            groupVo.setDataSourceDesc(DataSource.ofCode(dataSource).getDescription());
            groupVo.setGroupVos(assembleViewGroupVos(groups, req));
            widgetVoList.add(groupVo);
        }
        return widgetVoList;
    }

    private List<DynamicViewGroupVo> assembleViewGroupVos(List<DynamicViewGroup> groups, DynamicViewConfigReq req) {
        List<DynamicViewGroupVo> viewGroupVoList = new ArrayList<>();
        for (DynamicViewGroup viewGroup : groups) {
            LambdaQueryWrapper<DynamicViewConfig> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(DynamicViewConfig::getGroupId, viewGroup.getId());
            queryWrapper.orderByAsc(DynamicViewConfig::getSortOrder);
            List<DynamicViewConfig> viewConfigList = dynamicViewConfigMapper.selectList(queryWrapper);

            List<DynamicViewConfigVo> viewConfigVoList = new ArrayList<>();
            for (DynamicViewConfig dynamicViewConfig : viewConfigList) {
                List<DynamicColumnVo> columnVoList = new ArrayList<>();

                List<DynamicViewColumn> columnList = getDynamicViewColumnsByViewId(dynamicViewConfig.getId(), req.getFunctionType());
                for (DynamicViewColumn column : columnList) {
                    DynamicColumnVo columnVo = new DynamicColumnVo();
                    BeanUtils.copyProperties(column, columnVo);
                    columnVoList.add(columnVo);
                }
                DynamicViewConfigVo viewConfigVo = new DynamicViewConfigVo();
                viewConfigVo.setId(dynamicViewConfig.getId());
                viewConfigVo.setSubType(dynamicViewConfig.getSubType());
                viewConfigVo.setSubTypeName(dynamicViewConfig.getSubTypeName());
                viewConfigVo.setExtra(dynamicViewConfig.getExtra());
                viewConfigVo.setDrillTable(dynamicViewConfig.getDrillTable());
                viewConfigVo.setDrillDimension(dynamicViewConfig.getDrillDimension());
                viewConfigVo.setColumnVoList(columnVoList);
                viewConfigVoList.add(viewConfigVo);
            }

            DynamicViewGroupVo groupVo = new DynamicViewGroupVo();
            groupVo.setType(HomeType.ofCode(viewGroup.getType()).getDescription());
            // groupVo.setDataSource(DataSource.ofCode(viewGroup.getDataSource()).getDescription());
            // groupVo.setFunctionType(FunctionType.ofCode(viewGroup.getFunctionType()).getDescription());
            viewGroupVoList.add(groupVo);
            groupVo.setViewConfigVoList(viewConfigVoList);
        }
        return viewGroupVoList;
    }
}